package org.jordens.jdbcspy.testutil;

import org.jordens.jdbcspy.jmx.*;
import org.jordens.jdbcspy.testutil.callbacks.*;
import org.testng.*;

/**
 * A TestNG listener that will track JDBCSpy statistics on a per-test basis.
 *
 * @author Adam Jordens
 */
public class JDBCSpyListener extends TestListenerAdapter
{
    private final JDBCSpyMBean jdbcSpy;
    private final JDBCSpyListenerCallback callback;

    /**
     * @param jdbcSpy JDBCSpyMBean reference (not-null)
     * @param callback JDBCSpyListenerCallback 
     */
    public JDBCSpyListener(JDBCSpyMBean jdbcSpy, JDBCSpyListenerCallback callback)
    {
        if (jdbcSpy == null)
        {
            throw new NullPointerException("Reference to JDBCSpyMBean cannot be null");
        }

        this.jdbcSpy = jdbcSpy;

        if (callback != null)
        {
            this.callback = callback;
        }
        else
        {
            this.callback = new DefaultJDBCSpyListenerCallback();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onTestStart(ITestResult iTestResult)
    {
        callback.onStart(jdbcSpy, iTestResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onTestSuccess(ITestResult iTestResult)
    {
        callback.onFinish(jdbcSpy, iTestResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onTestFailure(ITestResult iTestResult)
    {
        callback.onFinish(jdbcSpy, iTestResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onTestSkipped(ITestResult iTestResult)
    {
        callback.onFinish(jdbcSpy, iTestResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult iTestResult)
    {
        callback.onFinish(jdbcSpy, iTestResult);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onStart(ITestContext iTestContext)
    {
        callback.onSuiteStart();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onFinish(ITestContext iTestContext)
    {
        callback.onSuiteFinish();
    }

    /**
     * A callback interface for responding to start/finish test events.
     */
    public interface JDBCSpyListenerCallback
    {
        void onSuiteStart();
        void onStart(JDBCSpyMBean jdbcSpy, ITestResult testResult);
        void onFinish(JDBCSpyMBean jdbcSpy, ITestResult testResult);
        void onSuiteFinish();
    }
}
